package com.simple.common.utils.ExcelUtil;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.simple.common.exception.RRException;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Data
@NoArgsConstructor
public class ExcelListener extends AnalysisEventListener {

    public ExcelListener(Integer headLineNum) {
        this.headLineNum = headLineNum;
    }

    private Integer headLineNum;
    /**
     * 可以通过实例获取该值
     */
    private List<Object> dataList = new ArrayList<>();
    /**
     * 临时存储合并单元格
     */
    private List<CellExtra> cellExtraList = new ArrayList<>();

    //todo 完善各个字段去前后空格
    @Override
    public void invoke(Object object, AnalysisContext context) {
        //数据存储到list，供批量处理，或后续自己业务逻辑处理。
        dataList.add(object);
          /*
        如数据过大，可以进行定量分批处理
        if(dataList.size()>=200){
            handleBusinessLogic();
            dataList.clear();
        }
         */
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        String msg = "第%s行的数据解析失败,请核对数据格式";
        throw new RRException(String.format(msg, dataList.size() + 2));
    }

    /**
     * 获取合并单元格信息 解析文件的时候也要把表头行数读取进来用于计算
     */
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        if (extra.getLastRowIndex() > headLineNum && extra.getType() == CellExtraTypeEnum.MERGE) {
            cellExtraList.add(extra);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //非必要语句，查看导入的数据
        System.out.println("cellExtraList的数据条数为: " + cellExtraList.size());
        ExcelProperty excelProperty;
        Object value;
        Field[] declaredFields;
        Object target;
        for (CellExtra extra : cellExtraList) {
            //合并单元格的值
            value = null;
            //需要填充的字段名
            String needToFill = "";
            //行
            int row = extra.getFirstRowIndex() - headLineNum;
            //列
            Integer column = extra.getFirstColumnIndex();
            target = dataList.get(row);
            declaredFields = target.getClass().getDeclaredFields();

            //找到合并单元格的值
            for (Field f : declaredFields) {
                f.setAccessible(true);
                excelProperty = f.getAnnotation(ExcelProperty.class);
                if (excelProperty == null) {
                    continue;
                }
                if (excelProperty.index() < 0){
                    throw new RRException("如解析的是存在合并单元格excel,请务必在ExcelProperty上增加index属性");
                }

                if (excelProperty.index() == column) {
                    try {
                        value = f.get(target);
                        needToFill = f.getName();
                        break;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            //填充值 减去表头数即可
            Object data;
            for (int k = extra.getFirstRowIndex() + 1; k <= extra.getLastRowIndex(); k++) {
                try {
                    data = dataList.get(k - headLineNum);
                    Field f = data.getClass().getDeclaredField(needToFill);
                    f.setAccessible(true);
                    f.set(data, value);
                } catch (Exception e) {

                }
            }
        }
        System.out.println("excel导入的数据条数为: " + dataList.size());
    }
}
